package com.maodou.core.utils.permission

import android.app.Activity
import android.app.AlertDialog
import android.app.Dialog
import android.content.Context
import android.content.DialogInterface
import android.os.Build
import android.os.Build.VERSION_CODES
import android.text.TextUtils
import android.widget.Toast
import androidx.activity.ComponentActivity
import androidx.appcompat.app.AppCompatActivity
import com.hjq.permissions.OnPermissionCallback
import com.hjq.permissions.OnPermissionInterceptor
import com.hjq.permissions.XXPermissions
import com.hjq.permissions.permission.PermissionGroups
import com.hjq.permissions.permission.PermissionNames
import com.hjq.permissions.permission.base.IPermission
import com.maodou.core.R
import com.maodou.core.utils.permission.PermissionConverter.getNickNamesByPermissions

/**
 * @Author Xing
 * @CreateTime 2025年08月29日
 * @Description 权限申请拦截器
 */
class PermissionInterceptor : OnPermissionInterceptor {

    override fun onRequestPermissionEnd(
        activity: Activity, skipRequest: Boolean,
        requestList: List<IPermission>,
        grantedList: List<IPermission>,
        deniedList: List<IPermission>,
        callback: OnPermissionCallback?
    ) {
        callback?.onResult(grantedList, deniedList)

        if (deniedList.isEmpty()) {
            return
        }
        val doNotAskAgain = XXPermissions.isDoNotAskAgainPermissions(activity, deniedList)
        val permissionHint = generatePermissionHint(activity, deniedList, doNotAskAgain)
        if (!doNotAskAgain) {
            // 如果没有勾选不再询问选项，就弹 Toast 提示给用户
            Toast.makeText(activity,permissionHint,Toast.LENGTH_LONG).show()
            return
        }

        // 如果勾选了不再询问选项，就弹 Dialog 引导用户去授权
        showPermissionSettingDialog(activity, requestList, deniedList, callback, permissionHint)
    }

    private fun showPermissionSettingDialog(
        activity: Activity,
        requestList: List<IPermission>,
        deniedList: List<IPermission>,
        callback: OnPermissionCallback?,
        permissionHint: String
    ) {
        if (activity.isFinishing || activity.isDestroyed) {
            return
        }

        val dialogTitle = activity.getString(R.string.common_permission_alert)
        val confirmButtonText = activity.getString(R.string.common_permission_go_to_authorization)
        val confirmListener =
            DialogInterface.OnClickListener { dialog: DialogInterface, _: Int ->
                dialog.dismiss()
                XXPermissions.startPermissionActivity(
                    activity, deniedList,
                    OnPermissionCallback { _, _ ->
                        val latestDeniedList =
                            XXPermissions.getDeniedPermissions(activity, requestList)
                        val allGranted = latestDeniedList.isEmpty()
                        if (!allGranted) {
                            // 递归显示对话框，让提示用户授权，只不过对话框是可取消的，用户不想授权了，随时可以点击返回键或者对话框蒙层来取消显示
                            showPermissionSettingDialog(
                                activity, requestList, latestDeniedList, callback,
                                generatePermissionHint(activity, latestDeniedList, true)
                            )
                            return@OnPermissionCallback
                        }

                        if (callback == null) {
                            return@OnPermissionCallback
                        }
                        // 用户全部授权了，回调成功给外层监听器，免得用户还要再发起权限申请
                        callback.onResult(requestList, latestDeniedList)
                    })
            }

        // 另外这里需要判断 Activity 的类型来申请权限，这是因为只有 AppCompatActivity 才能调用 Support 库的 AlertDialog 来显示，否则会出现报错
        // java.lang.IllegalStateException: You need to use a Theme.AppCompat theme (or descendant) with this activity
        // 为什么不直接用 App 包 AlertDialog 来显示，而是两套规则？因为 App 包 AlertDialog 是系统自带的类，不同 Android 版本展现的样式可能不太一样
        // 如果这个 Android 版本比较低，那么这个对话框的样式就会变得很丑，准确来讲也不能说丑，而是当时系统的 UI 设计就是那样，它只是跟随系统的样式而已
        val dialog: Dialog = if (activity is AppCompatActivity || activity is ComponentActivity) {
            AlertDialog.Builder(activity)
                .setTitle(dialogTitle)
                .setMessage(permissionHint) // 这里需要设置成可取消的，这样用户不想授权了，随时可以点击返回键或者对话框蒙层来取消显示 Dialog
                .setCancelable(true)
                .setPositiveButton(confirmButtonText, confirmListener)
                .create()
        } else {
            AlertDialog.Builder(activity)
                .setTitle(dialogTitle)
                .setMessage(permissionHint) // 这里需要设置成可取消的，这样用户不想授权了，随时可以点击返回键或者对话框蒙层来取消显示 Dialog
                .setCancelable(true)
                .setPositiveButton(confirmButtonText, confirmListener)
                .create()
        }
        dialog.show()
    }

    /**
     * 生成权限提示文案
     */
    private fun generatePermissionHint(activity: Activity, deniedList: List<IPermission>, doNotAskAgain: Boolean): String {
        val deniedPermissionCount = deniedList.size
        var deniedLocationPermissionCount = 0
        var deniedSensorsPermissionCount = 0
        var deniedHealthPermissionCount = 0
        for (deniedPermission: IPermission in deniedList) {
            val permissionGroup = deniedPermission.getPermissionGroup(activity)
            if (TextUtils.isEmpty(permissionGroup)) {
                continue
            }
            if (PermissionGroups.LOCATION == permissionGroup) {
                deniedLocationPermissionCount++
            } else if (PermissionGroups.SENSORS == permissionGroup) {
                deniedSensorsPermissionCount++
            } else if (XXPermissions.isHealthPermission(deniedPermission)) {
                deniedHealthPermissionCount++
            }
        }

        if (deniedLocationPermissionCount == deniedPermissionCount && Build.VERSION.SDK_INT >= VERSION_CODES.Q) {
            if (deniedLocationPermissionCount == 1) {
                if (XXPermissions.equalsPermission(
                        deniedList[0],
                        PermissionNames.ACCESS_BACKGROUND_LOCATION
                    )
                ) {
                    return activity.getString(
                        R.string.common_permission_fail_hint_1,
                        activity.getString(R.string.common_permission_location_background),
                        getBackgroundPermissionOptionLabel(activity)
                    )
                } else if (Build.VERSION.SDK_INT >= VERSION_CODES.S &&
                    XXPermissions.equalsPermission(
                        deniedList[0],
                        PermissionNames.ACCESS_FINE_LOCATION
                    )
                ) {
                    // 如果请求的定位权限中，既包含了精确定位权限，又包含了模糊定位权限或者后台定位权限，
                    // 但是用户只同意了模糊定位权限的情况或者后台定位权限，并没有同意精确定位权限的情况，就提示用户开启确切位置选项
                    // 需要注意的是 Android 12 才将模糊定位权限和精确定位权限的授权选项进行分拆，之前的版本没有区分得那么仔细
                    return activity.getString(
                        R.string.common_permission_fail_hint_3,
                        activity.getString(R.string.common_permission_location_fine),
                        activity.getString(R.string.common_permission_location_fine_option)
                    )
                }
            } else {
                if (XXPermissions.containsPermission(
                        deniedList,
                        PermissionNames.ACCESS_BACKGROUND_LOCATION
                    )
                ) {
                    if (Build.VERSION.SDK_INT >= VERSION_CODES.S &&
                        XXPermissions.containsPermission(
                            deniedList,
                            PermissionNames.ACCESS_FINE_LOCATION
                        )
                    ) {
                        return activity.getString(
                            R.string.common_permission_fail_hint_2,
                            activity.getString(R.string.common_permission_location),
                            getBackgroundPermissionOptionLabel(activity),
                            activity.getString(R.string.common_permission_location_fine_option)
                        )
                    } else {
                        return activity.getString(
                            R.string.common_permission_fail_hint_1,
                            activity.getString(R.string.common_permission_location),
                            getBackgroundPermissionOptionLabel(activity)
                        )
                    }
                }
            }
        } else if (deniedSensorsPermissionCount == deniedPermissionCount && Build.VERSION.SDK_INT >= VERSION_CODES.TIRAMISU) {
            if (deniedPermissionCount == 1) {
                if (XXPermissions.equalsPermission(
                        deniedList[0],
                        PermissionNames.BODY_SENSORS_BACKGROUND
                    )
                ) {
                    return if (Build.VERSION.SDK_INT >= VERSION_CODES.BAKLAVA) {
                        activity.getString(
                            R.string.common_permission_fail_hint_1,
                            activity.getString(R.string.common_permission_health_data_background),
                            activity.getString(R.string.common_permission_health_data_background_option)
                        )
                    } else {
                        activity.getString(
                            R.string.common_permission_fail_hint_1,
                            activity.getString(R.string.common_permission_body_sensors_background),
                            getBackgroundPermissionOptionLabel(activity)
                        )
                    }
                }
            } else {
                if (doNotAskAgain) {
                    return if (Build.VERSION.SDK_INT >= VERSION_CODES.BAKLAVA) {
                        activity.getString(
                            R.string.common_permission_fail_hint_1,
                            activity.getString(R.string.common_permission_health_data),
                            activity.getString(R.string.common_permission_allow_all_option)
                        )
                    } else {
                        activity.getString(
                            R.string.common_permission_fail_hint_1,
                            activity.getString(R.string.common_permission_body_sensors),
                            getBackgroundPermissionOptionLabel(activity)
                        )
                    }
                }
            }
        } else if (deniedHealthPermissionCount == deniedPermissionCount && Build.VERSION.SDK_INT >= VERSION_CODES.BAKLAVA) {
            when (deniedPermissionCount) {
                1 -> if (XXPermissions.equalsPermission(
                        deniedList[0],
                        PermissionNames.READ_HEALTH_DATA_IN_BACKGROUND
                    )
                ) {
                    return activity.getString(
                        R.string.common_permission_fail_hint_3,
                        activity.getString(R.string.common_permission_health_data_background),
                        activity.getString(R.string.common_permission_health_data_background_option)
                    )
                } else if (XXPermissions.equalsPermission(
                        deniedList[0],
                        PermissionNames.READ_HEALTH_DATA_HISTORY
                    )
                ) {
                    return activity.getString(
                        R.string.common_permission_fail_hint_3,
                        activity.getString(R.string.common_permission_health_data_past),
                        activity.getString(R.string.common_permission_health_data_past_option)
                    )
                }

                2 -> if (XXPermissions.containsPermission(
                        deniedList,
                        PermissionNames.READ_HEALTH_DATA_HISTORY
                    ) &&
                    XXPermissions.containsPermission(
                        deniedList,
                        PermissionNames.READ_HEALTH_DATA_IN_BACKGROUND
                    )
                ) {
                    return activity.getString(
                        R.string.common_permission_fail_hint_3,
                        activity.getString(R.string.common_permission_health_data_past) + activity.getString(
                            R.string.common_permission_and
                        ) + activity.getString(R.string.common_permission_health_data_background),
                        activity.getString(R.string.common_permission_health_data_past_option) + activity.getString(
                            R.string.common_permission_and
                        ) + activity.getString(R.string.common_permission_health_data_background_option)
                    )
                } else if (XXPermissions.containsPermission(
                        deniedList,
                        PermissionNames.READ_HEALTH_DATA_HISTORY
                    )
                ) {
                    return activity.getString(
                        R.string.common_permission_fail_hint_2,
                        activity.getString(R.string.common_permission_health_data) + activity.getString(
                            R.string.common_permission_and
                        ) + activity.getString(R.string.common_permission_health_data_past),
                        activity.getString(R.string.common_permission_allow_all_option),
                        activity.getString(R.string.common_permission_health_data_background_option)
                    )
                } else if (XXPermissions.containsPermission(
                        deniedList,
                        PermissionNames.READ_HEALTH_DATA_IN_BACKGROUND
                    )
                ) {
                    return activity.getString(
                        R.string.common_permission_fail_hint_2,
                        activity.getString(R.string.common_permission_health_data) + activity.getString(
                            R.string.common_permission_and
                        ) + activity.getString(R.string.common_permission_health_data_background),
                        activity.getString(R.string.common_permission_allow_all_option),
                        activity.getString(R.string.common_permission_health_data_background_option)
                    )
                }

                else -> if (XXPermissions.containsPermission(
                        deniedList,
                        PermissionNames.READ_HEALTH_DATA_HISTORY
                    ) &&
                    XXPermissions.containsPermission(
                        deniedList,
                        PermissionNames.READ_HEALTH_DATA_IN_BACKGROUND
                    )
                ) {
                    return activity.getString(
                        R.string.common_permission_fail_hint_2,
                        activity.getString(R.string.common_permission_health_data) + activity.getString(
                            R.string.common_permission_and
                        ) + activity.getString(R.string.common_permission_health_data_past) + activity.getString(
                            R.string.common_permission_and
                        ) + activity.getString(R.string.common_permission_health_data_background),
                        activity.getString(R.string.common_permission_allow_all_option),
                        activity.getString(R.string.common_permission_health_data_past_option) + activity.getString(
                            R.string.common_permission_and
                        ) + activity.getString(R.string.common_permission_health_data_background_option)
                    )
                }
            }
            return activity.getString(
                R.string.common_permission_fail_hint_1,
                activity.getString(R.string.common_permission_health_data),
                activity.getString(R.string.common_permission_allow_all_option)
            )
        }

        return activity.getString(
            if (doNotAskAgain) R.string.common_permission_fail_assign_hint_1 else R.string.common_permission_fail_assign_hint_2,
            getNickNamesByPermissions(activity, deniedList)
        )
    }

    /**
     * 获取后台权限的《始终允许》选项的文案
     */
    private fun getBackgroundPermissionOptionLabel(context: Context): String {
        val packageManager = context.packageManager
        if (packageManager != null && Build.VERSION.SDK_INT >= VERSION_CODES.R) {
            val backgroundPermissionOptionLabel = packageManager.backgroundPermissionOptionLabel
            if (!TextUtils.isEmpty(backgroundPermissionOptionLabel)) {
                return backgroundPermissionOptionLabel.toString()
            }
        }

        return context.getString(R.string.common_permission_allow_all_the_time_option)
    }
}